package com.myapp.msg.base;

import java.io.IOException;
import java.nio.ByteBuffer;

import com.myapp.data.global.Instances;
import com.myapp.msg.define.MsgConfigBean;

public abstract class BaseMsg {
	// 消息配置bean
	private MsgConfigBean msgConfigBean;

	// 读数据时的缓冲区
	private ByteBuffer readByteBuffer = null;

	// 写数据时的缓冲区
	private ByteBuffer writeByteBuffer = null;

	public MsgConfigBean getMsgConfigBean() {
		return msgConfigBean;
	}

	public void setMsgConfigBean(MsgConfigBean msgConfigBean) {
		this.msgConfigBean = msgConfigBean;
	}

	public boolean readBoolean() throws IOException {
		if (this.readByteBuffer.get() == 0) {
			return false;
		} else {
			return true;
		}
	}

	public byte readByte() throws IOException {
		return this.readByteBuffer.get();
	}

	public short readShort() throws IOException {
		return this.readByteBuffer.getShort();
	}

	public int readInt() throws IOException {
		return this.readByteBuffer.getInt();
	}

	public long readLong() throws IOException {
		return this.readByteBuffer.getLong();
	}

	public String readString() throws IOException {
		int length = this.readByteBuffer.getInt();
		byte[] temp = new byte[length];
		this.readByteBuffer.get(temp);
		String data = new String(temp, "UTF-8");
		return data;
	}

	/**
	 * 校验Buffer长度是否足够，不够时，扩增到原来的1.5倍
	 * 
	 * @param size
	 *            要增加的长度
	 */
	private void checkBufferLimit(int size) {
		int limit = this.writeByteBuffer.limit();
		int length = this.writeByteBuffer.position() + size;
		if (length > limit) {
			ByteBuffer switchBuffer = ByteBuffer.allocate(limit * 3 / 2);
			switchBuffer.put(writeByteBuffer);
			this.writeByteBuffer = switchBuffer;
		}
	}

	public void writeBoolean(boolean data) throws IOException {
		this.checkBufferLimit(1);
		if (data) {
			this.writeByteBuffer.put((byte) 1);
		} else {
			this.writeByteBuffer.put((byte) 0);
		}
	}

	public void writeByte(byte data) throws IOException {
		this.checkBufferLimit(1);
		this.writeByteBuffer.put(data);
	}

	public void writeShort(short data) throws IOException {
		this.checkBufferLimit(2);
		this.writeByteBuffer.putShort(data);
	}

	public void writeInt(int data) throws IOException {
		this.checkBufferLimit(4);
		this.writeByteBuffer.putInt(data);
	}

	public void writeLong(long data) throws IOException {
		this.checkBufferLimit(8);
		this.writeByteBuffer.putLong(data);
	}

	public void writeString(String data) throws IOException {
		byte[] data_ = data.getBytes("UTF-8");
		this.checkBufferLimit((data_.length + 4));
		this.writeByteBuffer.putInt(data_.length);
		this.writeByteBuffer.put(data_);
	}

	public void readBase(ByteBuffer readByteBuffer) throws IOException {
		this.readByteBuffer = readByteBuffer;
		this.read();
	}

	public ByteBuffer writeBase(ByteBuffer writeByteBuffer) throws IOException {
		this.writeByteBuffer = writeByteBuffer;
		// 添加消息的type
		if (this.msgConfigBean == null) {
			this.msgConfigBean = Instances.getMsgContainer().getMsgConfigBean(
					this.getClass());
			this.writeByteBuffer.putShort(this.msgConfigBean.getId());
			this.write();
		} else {
			throw new IllegalArgumentException(String.format(
					"Can not found MsgConfigBean[%s]", this.getClass()
							.getName()));
		}

		return this.writeByteBuffer;
	}

	public abstract void read() throws IOException;

	public abstract void write() throws IOException;

}
